﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Timers;
using System.Web;
using System.Transactions;
using FTBS.Models.Entities;
using System.Data;
using System.Data.Objects;

namespace FTBS.Common
{
    public class Utilities
    {
        private const double intevalTime = 60000; // set up an interval time equals 10 minute
        private static Timer intervalTimeChecker = new Timer(intevalTime); // set up a timer with 10 minutes interval
        private static FilmTicketBookingSystemEntities _entities = new FilmTicketBookingSystemEntities();

        /// <summary>
        /// Foreach moment of time, this function will run UpdateAndDeleteSchedules function
        /// </summary>
        public static void CheckOnTime()
        {
            intervalTimeChecker.Elapsed += new ElapsedEventHandler(UpdateSystem);
            intervalTimeChecker.Enabled = true;
        }

        /// <summary>
        /// Delete schedules, which is out of date to create tickets
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="e"></param>
        public static void UpdateSystem(object obj, ElapsedEventArgs e)
        {
            TransactionScope tran = new TransactionScope();
            using (tran)
            {
                try
                {
                    var listUpdatingSchedules = from schedule in _entities.Schedules
                                                where
                                                    //schedule.Date <= DateTime.Today &&
                                                schedule.IsDeleted == false
                                                select schedule;
                    foreach (var item in listUpdatingSchedules)
                    {
                        // schedules are in dealine for creating ticket at current day, 
                        // if they have not been created tickets, they will be delete
                        if (item.Date == DateTime.Today.Date)
                        {
                            if (item.IsCreateTicket == false)
                            {
                                //Firstly, delete tickets of current schedule
                                // get list tikets of current schedule
                                var listDeletingTickets = from ticket in _entities.Tickets
                                                          where ticket.IsDeleted == false
                                                                && ticket.Status == false
                                                                && ticket.ScheduleId == item.ScheduleId
                                                          select ticket;
                                //Delete each ticket in the list
                                foreach (var tItem in listDeletingTickets)
                                {
                                    tItem.IsDeleted = true;
                                    _entities.Entry(tItem).State = EntityState.Modified;
                                    _entities.SaveChanges();
                                }

                                //Then, delete schedule   
                                item.IsDeleted = true;
                                _entities.Entry(item).State = EntityState.Modified;
                                _entities.SaveChanges();
                            }
                            else
                            {
                                // sellingDate is a deadline for update schedule status
                                var sellingDate = item.Date.AddDays(-item.Theater.DeadlineCreateTicket);
                                if (item.IsCreateTicket == true)
                                {
                                    // it just uses for update schedule at its deadline for creating ticket
                                    // because it is the last day, when its tickets are already to sell
                                    // the staff can update it sooner by hand in staff's home page
                                    if (sellingDate == DateTime.Today)
                                    {
                                        //Update schedule's status to    
                                        item.IsActive = true;
                                        _entities.Entry(item).State = EntityState.Modified;
                                        _entities.SaveChanges();
                                    }
                                } 
                            }
                        }
                        // if shcedules are out of date, it and its ticket will be marked as deleted
                        else if (item.Date < DateTime.Today.Date)
                        {
                            //Firstly, delete tickets of current schedule
                            // get list tikets of current schedule
                            var listDeletingTickets = from ticket in _entities.Tickets
                                                      where ticket.IsDeleted == false
                                                            && ticket.Status == false
                                                            && ticket.ScheduleId == item.ScheduleId
                                                      select ticket;
                            //Delete each ticket in the list
                            foreach (var tItem in listDeletingTickets)
                            {
                                tItem.IsDeleted = true;
                                _entities.Entry(tItem).State = EntityState.Modified;
                                _entities.SaveChanges();
                            }

                            //Then, delete schedule   
                            item.IsDeleted = true;
                            _entities.Entry(item).State = EntityState.Modified;
                            _entities.SaveChanges();
                            //Schedule deletingSchedule = item.schedule;
                            //deletingSchedule.IsDeleted = true;
                            //_entities.Entry(deletingSchedule).State = EntityState.Modified;
                        }
                    }

                    tran.Complete();
                }
                catch (Exception)
                {
                    tran.Dispose();
                    throw;
                }
            }
        }

        /// <summary>
        /// Update status of schedules, which contain comming-soon films and has tickets but the status isActive is false
        /// </summary>
        public static void UpdateScheduleStatus() {
            var listUpdatingSchedules = from schedule in _entities.Schedules
                                        where
                                        schedule.Date == DateTime.Today &&
                                        schedule.IsDeleted == false
                                        select schedule;
            foreach( var item in listUpdatingSchedules)
            {
                // sellingDate is a deadline for update schedule status
                var sellingDate = item.Date.AddDays(-item.Theater.DeadlineCreateTicket);
                if (item.IsCreateTicket == true)
                {
                    // it just uses for update schedule at its deadline for creating ticket
                    // because it is the last day, when its tickets are already to sell
                    // the staff can update it sooner by hand in staff's home page
                    if (sellingDate == DateTime.Today)
                    {
                        //Update schedule's status to    
                        item.IsActive = true;
                        _entities.Entry(item).State = EntityState.Modified;
                        _entities.SaveChanges();
                    }
                }  
                
            }
        }

        /// <summary>
        /// Delete promotion if it is out of date
        /// </summary>
        public static void DeleteOutOfDatePromotion() { 
           var outOfDatePromotions = from promotion in _entities.Promotions
                                          where promotion.IsDeleted == false
                                                && promotion.ToDate < DateTime.Today
                                          select promotion;
           foreach (var promotion in outOfDatePromotions) {
               promotion.IsDeleted = true;    
               _entities.Entry(promotion).State = EntityState.Modified;
               _entities.SaveChanges();
           }
        }
    }
}